#include <iostream>

#if 0
    template<typename T>
    // 传引用的话就接不了右值，用const修饰的话就改不了值
    void func(T a)
    {
        std::cout <<a << std::endl;
    }

    int main()
    {
        int a = 10;
        func(a);

        return 0;
    }
#endif

#if 0
    template<typename T>
    // 万能引用：模板参数 + &&
    // 既能接左值 又能接右值
    void func(T &&a) 
    {
        std::cout <<a << std::endl;
    }

    int main()
    {
        int a = 10;
        func(a);

        return 0;
    }
#endif

#if 0
    void print(int &a)
    {
        std::cout << "左值引用" << std::endl;
        std::cout << a << std::endl;
    }

    void print(int &&a)
    {
        std::cout << "右值引用" << std::endl;
        std::cout << a << std::endl;
    }


    template<typename T>
    // 万能引用：模板参数 + &&
    // 既能接左值 又能接右值
    void func(T &&a) 
    {
        // 万能引用函数中调用别的函数，万能引用参数会被当做左值
        print(a);
    }

    int main()
    {
        int a = 10;
        func(a);
        func(10);

        return 0;
    }
#endif

#if 1
    void print(int &a)
    {
        std::cout << "左值引用" << std::endl;
        std::cout << a << std::endl;
    }

    void print(int &&a)
    {
        std::cout << "右值引用" << std::endl;
        std::cout << a << std::endl;
    }


    template<typename T>
    // 万能引用：模板参数 + &&
    // 既能接左值 又能接右值
    void func(T &&a) 
    {
        // 完美转发：保持原有的左右值属性
        print(std::forward<T>(a));
    }

    int main()
    {
        int a = 10;
        func(a);
        func(10);

        return 0;
    }
#endif